/**
 * Copyright (c) 2009 Teoti Graphix, LLC See:
 *     http://tkarchitecture.teotigraphix.org
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * 
 * @author Michael Schmalle mschmalle@teotigraphix.com
 */
package test.suite.dxframework.patterns.manager
{

import mx.events.FlexEvent;

import org.flexunit.Assert;
import org.flexunit.async.Async;
import org.fluint.uiImpersonation.UIImpersonator;
import org.teotigraphix.dx.interfaces.IComponentModel;
import org.teotigraphix.dx.interfaces.IModelLayer;
import org.teotigraphix.dx.patterns.manager.ModelManager;
import org.teotigraphix.dx.patterns.model.ComponentModel;

import test.suite.dxframework.support.component.TestComponent;
import test.suite.dxframework.support.model.TestModel;

/**
 * @author Michael Schmalle
 * @date 08-11-09
 */
public class TC_ModelManager
{
	protected var component:TestComponent;
	//protected var behavior:IconBehavior;
	
	[Before(ui,async)]
	public function setUp():void
	{
		component = new TestComponent();
		
		Async.proceedOnEvent(this, component, FlexEvent.CREATION_COMPLETE);
		UIImpersonator.addChild( component );
	}
	
	[After]
	public function tearDown():void
	{
		UIImpersonator.removeChild( component );
		component = null;
	}
	
	[Test]
	public function test_call_createModelLayer():void
	{
		// adds layer to cache
		// sets layer.component
		// calls layer.activate()
		var layer:IModelLayer = ModelManager.createModelLayer(component);
		
		Assert.assertNotNull( "layer null", layer );
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		Assert.assertStrictlyEquals( "layer.component not equal", component, layer.component );
		Assert.assertTrue( "!layer.isActive", layer.isActive );
	}
	
	[Test]
	public function test_call_getModelLayer():void
	{
		var layer:IModelLayer = ModelManager.createModelLayer(component);
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		var other:IModelLayer = ModelManager.getModelLayer(component);
		Assert.assertStrictlyEquals( "layer not equal", layer, other );
	}
	
	[Test]
	public function test_call_hasModelLayer():void
	{
		var layer:IModelLayer = ModelManager.createModelLayer(component);
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
	}
	
	[Test]
	public function test_call_registerModelAPI():void
	{
		// TODO (mschmalle) impl unit test
	}
	
	
	[Test]
	public function test_call_createModel():void
	{
		
	}	// TODO (mschmalle) impl unit test
	
	[Test]
	public function test_call_registerModel():void
	{
		var model:TestModel = new TestModel();
		ModelManager.registerModel(component, TestModel, model);
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		Assert.assertTrue( "!ModelManager.hasModel()", ModelManager.hasModel( component, TestModel ) );
		Assert.assertTrue( "model.isActive", model.isActive );
		var other:IComponentModel = ModelManager.getModel(component, TestModel);
		Assert.assertStrictlyEquals( "model not equal", model, other );
	}
	
	[Test]
	public function test_call_removeModel():void
	{
		var model:TestModel = new TestModel();
		ModelManager.registerModel(component, TestModel, model);
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		Assert.assertTrue( "!ModelManager.TestModel()", ModelManager.hasModel( component, TestModel ) );
		
		var other:IComponentModel = ModelManager.removeModel( component, TestModel );
		Assert.assertStrictlyEquals( "model not equal", model, other );
		Assert.assertFalse( "model.isActive", model.isActive );
		Assert.assertFalse( "ModelManager.hasModel()", ModelManager.hasModel( component, TestModel ) );
	}
	
	[Test]
	public function test_call_hasModel():void
	{
		var model:TestModel = new TestModel();
		ModelManager.registerModel(component, TestModel, model);
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		Assert.assertTrue( "!ModelManager.TestModel()", ModelManager.hasModel( component, TestModel ) );		
	}
	
	[Test]
	public function test_call_getModel():void
	{
		var model:TestModel = new TestModel();
		ModelManager.registerModel(component, TestModel, model);
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		Assert.assertTrue( "!ModelManager.hasModel()", ModelManager.hasModel( component, TestModel ) );
		Assert.assertTrue( "model.isActive", model.isActive );
		var other:IComponentModel = ModelManager.getModel(component, TestModel);
		Assert.assertStrictlyEquals( "model not equal", model, other );		
	}
	
	[Test]
	public function test_call_getModels():void
	{
		var model1:TestModel = new TestModel();
		var model2:TestModel = new TestModel();
		var model3:TestModel = new TestModel();
		
		ModelManager.registerModel(component, TestModel, model1);
		ModelManager.registerModel(component, IComponentModel, model2);	
		ModelManager.registerModel(component, ComponentModel, model3);
		
		Assert.assertTrue( "!ModelManager.hasModel()", ModelManager.hasModel( component, TestModel ) );
		Assert.assertTrue( "!ModelManager.hasModel()", ModelManager.hasModel( component, IComponentModel ) );
		Assert.assertTrue( "!ModelManager.hasModel()", ModelManager.hasModel( component, ComponentModel ) );
		
//		var models:Vector.<IComponentModel> = ModelManager.getModels( component ) as Vector.<IComponentModel>;
		// TODO temp work around for non-casting vectors
		var layer:IModelLayer = ModelManager.getModelLayer( component );
		var models:Array = layer.getModels();
		Assert.assertNotNull( "models null", models );
		
		Assert.assertStrictlyEquals( "model1 not equal", model1, models[0] );	
		Assert.assertStrictlyEquals( "model2 not equal", model2, models[1] );	
		Assert.assertStrictlyEquals( "model3 not equal", model3, models[2] );	
	}
	
	[Test]
	public function test_call_activate():void
	{
		var layer:IModelLayer = ModelManager.createModelLayer(component);
		
		Assert.assertNotNull( "layer null", layer );
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		Assert.assertTrue( "!layer.isActive", layer.isActive );		
	}
	
	[Test]
	public function test_call_deactivate():void
	{
		var layer:IModelLayer = ModelManager.createModelLayer(component);
		
		Assert.assertNotNull( "layer null", layer );
		Assert.assertTrue( "!ModelManager.hasModelLayer()", ModelManager.hasModelLayer( component ) );
		Assert.assertTrue( "!layer.isActive", layer.isActive );
		
		layer.deactivate( component );
		Assert.assertFalse( "layer.isActive", layer.isActive );		
	}
	
	[Test]
	public function test_call_activateCoreModel():void
	{
		var comp:TestComponent = new TestComponent();
		Assert.assertNull( "coreModel null", comp.coreModel );
		
		UIImpersonator.addChild( comp );
		
		Assert.assertNotNull( "coreModel null", comp.coreModel );
		Assert.assertStrictlyEquals( "", comp, comp.coreModel.component );
		//Assert.assertFalse( "coreModel.isActive", comp.coreModel.isActive );
		
		//comp.validateNow();
		// TKH.setCoreModel() calls core.activate(component)
		Assert.assertTrue( "!coreModel.isActive", comp.coreModel.isActive );
	}
	
	[Test]
	public function test_call_deactivateCoreModel():void
	{
		var comp:TestComponent = new TestComponent();
		
		Assert.assertNull( "coreModel null", comp.coreModel );
		
		UIImpersonator.addChild( comp );
		
		var model:IComponentModel = comp.coreModel;
		Assert.assertNotNull( "coreModel null", comp.coreModel );
		// TKH.setCoreModel() calls core.activate(component)
		Assert.assertTrue( "!coreModel.isActive", comp.coreModel.isActive );
		
		comp.coreModel = null;
		
		Assert.assertNull( "!coreModel null", comp.coreModel );
		// TKH.setCoreModel() calls core.activate(component)
		
		comp.validateProperties();
		
		Assert.assertFalse( "coreModel.isActive", model.isActive );
	}					
}
}